#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QMessageBox>
#include <QListView>
#include <QListWidget>
#include <QDateTime>
#include <QFile>
#include <QFileDialog>
#include <QTableWidget>
#include <QTreeView>
#include <QStandardItem>


typedef struct _DeviceInfo
{
    QString name;
    UINT device_type;  //设备类型
    UINT channel_count;//设备的通道个数
}DeviceInfo;

static const DeviceInfo kDeviceType[] = {
    {"ZCAN_USBCAN1",ZCAN_USBCAN1, 1},
    {"ZCAN_USBCAN2",ZCAN_USBCAN2, 2},
    {"ZCAN_USBCAN_E_U",ZCAN_USBCAN_E_U, 1},
    {"ZCAN_USBCAN_2E_U",ZCAN_USBCAN_2E_U, 2},
    {"ZCAN_USBCANFD_200U",ZCAN_USBCANFD_200U, 2},
    {"ZCAN_USBCANFD_100U",ZCAN_USBCANFD_100U, 1},
    {"ZCAN_USBCANFD_MINI",ZCAN_USBCANFD_MINI, 1},
};

typedef struct _BaudRateInfo
{
    QString name;
    QString value;
}BaudRateInfo;

static const BaudRateInfo kBaudRateInfo[] =
{
    {"500Kbps","500000"},
    {"250Kbps","250000"},
    {"125Kbps","125000"},
};

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    for(int i=0;i<7;i++)
    {
        ui->cmbDeviceType->addItem(kDeviceType[i].name);
    }

    for(int i=0;i<3;i++)
    {
        ui->cmbBaudrate->addItem(kBaudRateInfo[i].name);
    }

    ui->cmdDeviceIndex->addItem("0");
    ui->cmdDeviceIndex->addItem("1");

    CanSet = new CanSetModel;

    myThread = new QThread(this);

    CanSet->moveToThread(myThread);

    connect(this,&MainWindow::StartDataReceive,CanSet,&CanSetModel::DataReceive);

    connect(this,&MainWindow::destroyed,this,&MainWindow::CloseWin);

    connect(CanSet,&CanSetModel::DataUpdata,this,&MainWindow::UpdataReceive);

    Dbc = new DbcAnalysisModel(this);

    selectRow = -1;

}

MainWindow::~MainWindow()
{
    delete Dbc;
    delete ui;
}

void MainWindow::on_btnConnect_clicked()
{

    if(ui->btnConnect->isChecked() == false)
    {
        ui->btnConnect->setText("连接并启动");
        if(myThread->isRunning())
        {
            CanSet->CanClose();
            myThread->quit();
            myThread->wait();
        }
    }
    else
    {
        uint index = ui->cmbDeviceType->currentIndex();
        uint device_type = kDeviceType[index].device_type;
        uint deviceIndex = ui->cmdDeviceIndex->currentIndex();
        uint br =  ui->cmbBaudrate->currentIndex();

        char * brv  = kBaudRateInfo[br].value.toLatin1().data();

        CanSet->SetPara(device_type,deviceIndex,brv);

        bool isok = CanSet->CanConnect();

        if(isok)
        {
            ui->btnConnect->setText("断开连接");

            myThread->start();
            emit this->StartDataReceive();
        }
    }
}

void MainWindow::on_btnSend_clicked()
{
    bool ok;
    uint id = ui->txtSendId->text().toInt(&ok,16);
    uint FrmType = ui->cmbFrmaeType->currentIndex();

    QStringList list1 = ui->txtSendData->text().split(" ");
    int len = list1.size();
    unsigned char data[len];
    for( int i = 0; i < len; i++ )
    {
        data[i] = list1.at(i).toInt(&ok,16);
    }

    CanDataBase *cdb = new CanDataBase();
    cdb->SetIsSend(true);
    cdb->SetTime(QDateTime::currentDateTime());
    cdb->SetData(id,data,len,FrmType,false);

    if( CanSet->CanSend(cdb))
    {
        cdb->GetStringData();
        UpdataReceive(cdb);
    }
}

void MainWindow::CloseWin()
{
    if(myThread->isRunning())
    {
        CanSet->CanClose();
        // ui->btnConnect->setText("连接并启动");
        myThread->quit();
        myThread->wait();

        delete CanSet;
    }
}

void MainWindow::UpdataReceive(CanDataBase *cdb)
{
    QString  str;
    str += cdb->IsSend?"发送 ":"接收 ";
    // str += QString::number(cdb->sTime,'f',6);
    str += cdb->Time.toString("HH:mm:ss.zzz");
    str += "  ID:0x";
    str += QString::number(cdb->Id,16);
    str += cdb->IsExtendFrame?" 扩展帧 ":" 标准帧 ";
    str += " 数据：";
    str += cdb->StrData;

    QListWidgetItem *item = new QListWidgetItem(str);

    if(cdb->IsSend)
        item->setForeground(Qt::red);

    ui->lwDataDisplay->addItem(item);
    ui->lwDataDisplay->scrollToBottom();

    if(  ui->lwDataDisplay->count() >= 50)
        ui->lwDataDisplay->removeItemWidget(  ui->lwDataDisplay->takeItem(0));


    for(int i=0;i<this->Dbc->MsgList.size();i++)
    {
        if(this->Dbc->MsgList[i].Can.Id == cdb->Id)
        {
            this->Dbc->MsgList[i].getValue(cdb->Data,cdb->Len);

            model->item(i,2)->setText(cdb->StrData);

            for(int j=0;j<this->Dbc->MsgList[i].SingalList.size();j++)
            {
                model->item(i)->child(j,2)->setText(this->Dbc->MsgList[i].SingalList[j].GetStringValue());

                ui->widget->getRealValue(i,j,cdb->sTime,this->Dbc->MsgList[i].SingalList[j].GetValue());
            }
        }
    }
}



void MainWindow::on_btnOpenDbc_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                    "",
                                                    tr("DBC文件 (*.dbc)"));
    ui->lbFilename->setText( fileName);

    if(this->Dbc->GetList(fileName))
    {
        ui->trwLine->setHeaderLabels(QStringList()<<"名称"<<"注释");

        ui->tbMsg->setColumnCount(5);
        ui->tbMsg->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        ui->tbMsg->horizontalHeader()->setSectionResizeMode(2,QHeaderView::ResizeToContents);
        ui->tbMsg->horizontalHeader()->setSectionResizeMode(3,QHeaderView::ResizeToContents);
        ui->tbMsg->setHorizontalHeaderLabels(QStringList()<<"名称"<<"ID"<<"类型"<<"发送周期"<<"发送节点");
        ui->tbMsg->setRowCount(Dbc->MsgList.size());

        for(int i = 0;i<Dbc->MsgList.size();i++)
        {
            DbcMessageBase mb = Dbc->MsgList.at(i);
            QTableWidgetItem *tbi1 = new QTableWidgetItem(mb.Name);
            ui->tbMsg->setItem(i,0,tbi1);

            QTableWidgetItem *tbi2 = new QTableWidgetItem(QString::number(mb.Can.Id,16).toUpper());
            ui->tbMsg->setItem(i,1,tbi2);

            QTableWidgetItem *tbi3 = new QTableWidgetItem(mb.isMoto?"Motorola":"Intel");
            ui->tbMsg->setItem(i,2,tbi3);

            QTableWidgetItem *tbi5 = new QTableWidgetItem(QString::number(mb.SendCycle));
            ui->tbMsg->setItem(i,3,tbi5);

            QTableWidgetItem *tbi6 = new QTableWidgetItem(mb.SendNodeName);
            ui->tbMsg->setItem(i,4,tbi6);

            QTreeWidgetItem *tei =new QTreeWidgetItem(ui->trwLine);
            tei->setText(0,mb.Name);
            tei->setText(1,QString::number(mb.Can.Id,16).toUpper());

            for(int j=0;j<mb.SingalList.size();j++)
            {
                dbcsingalbase sb = mb.SingalList.at(j);
                QTreeWidgetItem *tei1 =new QTreeWidgetItem(tei);
                tei1->setToolTip(0,QString("%1,%2").arg(i).arg(j));
                tei1->setText(0,sb.Name);
                tei1->setText(1,sb.Note);
            }
        }

        getTreeView();
    }
}

void MainWindow::on_tbMsg_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
    if(currentRow != previousRow)
    {
        this->selectRow = currentRow;

        DbcMessageBase mb = Dbc->MsgList.at(currentRow);

        ui->tbSingal->setColumnCount(9);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(2,QHeaderView::ResizeToContents);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(3,QHeaderView::ResizeToContents);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(4,QHeaderView::ResizeToContents);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(5,QHeaderView::ResizeToContents);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(6,QHeaderView::ResizeToContents);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(7,QHeaderView::ResizeToContents);
        ui->tbSingal->horizontalHeader()->setSectionResizeMode(8,QHeaderView::ResizeToContents);
        //   ui->tbSingal->setColumnWidth(2,10);
        ui->tbSingal->setHorizontalHeaderLabels(QStringList()<<"名称"<<"注释"<<"LSB"<<"长度"<<"MSB"<<"类型"<<"分辩率"<<"偏移"<<"单位"<<"实际值");
        ui->tbSingal->setRowCount(mb.SingalList.size());

        for(int i=0;i<mb.SingalList.size();i++)
        {
            dbcsingalbase sb = mb.SingalList.at(i);

            QTableWidgetItem *tbi1 = new QTableWidgetItem(sb.Name);
            ui->tbSingal->setItem(i,0,tbi1);

            QTableWidgetItem *tbi2 = new QTableWidgetItem(sb.Note);
            ui->tbSingal->setItem(i,1,tbi2);

            QTableWidgetItem *tbi3 = new QTableWidgetItem(QString::number(sb.Start));
            ui->tbSingal->setItem(i,2,tbi3);

            QTableWidgetItem *tbi4 = new QTableWidgetItem(QString::number(sb.Number));
            ui->tbSingal->setItem(i,3,tbi4);

            QTableWidgetItem *tbi5 = new QTableWidgetItem(QString::number(sb.End));
            ui->tbSingal->setItem(i,4,tbi5);

            QTableWidgetItem *tbi6 = new QTableWidgetItem(sb.isEnum?"枚举":"整形");
            ui->tbSingal->setItem(i,5,tbi6);

            QTableWidgetItem *tbi7 = new QTableWidgetItem(QString::number(sb.Rate));
            ui->tbSingal->setItem(i,6,tbi7);

            QTableWidgetItem *tbi8 = new QTableWidgetItem(QString::number( sb.Offset));
            ui->tbSingal->setItem(i,7,tbi8);

            QTableWidgetItem *tbi9 = new QTableWidgetItem(sb.Unit);
            ui->tbSingal->setItem(i,8,tbi9);

            //            QTableWidgetItem *tbi10 = new QTableWidgetItem(sb.GetStringValue());
            //            ui->tbSingal->setItem(i,9,tbi10);
        }
    }
}



void MainWindow::getTreeView()
{
    model = new QStandardItemModel(ui->trwDisplay);
    model->setHorizontalHeaderLabels(QStringList()<<"名称"<<"注释"<<"实际值");
    for(int i = 0;i<Dbc->MsgList.size();i++)
    {
        DbcMessageBase mb = Dbc->MsgList.at(i);
        model->setItem(i,0,new QStandardItem(mb.Name));
        model->setItem(i,1,new QStandardItem(QString::number(mb.Can.Id,16).toUpper()));
        model->setItem(i,2,new QStandardItem(""));
        for(int j=0;j<mb.SingalList.size();j++)
        {
            dbcsingalbase sb = mb.SingalList.at(j);

            model->item(i)->setChild(j,0,new QStandardItem(sb.Name));
            model->item(i)->setChild(j,1,new QStandardItem(sb.Note));
            model->item(i)->setChild(j,2,new QStandardItem(sb.GetStringValue()));
        }
    }

    ui->trwDisplay->setModel(model);
    ui->trwDisplay->setEditTriggers(QAbstractItemView::NoEditTriggers);
}



void MainWindow::on_trwLine_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString str = item->toolTip(0);
    //  qDebug()<<str<<item->text(0);

    if(!str.isEmpty())
    {
        QStringList strs = str.split(",");

        int i=strs[0].toInt();
        int j=strs[1].toInt();
        qDebug()<<i<<","<<j;

        for(int k=0;k<ui->widget->Lines.size();k++)
        {
            if(ui->widget->Lines.at(k).lineI == i && ui->widget->Lines.at(k).lineJ == j)
            {
                return;
            }
        }

        LineBase line;
        line.lineI = i;
        line.lineJ = j;
        line.name = this->Dbc->MsgList.at(i).SingalList.at(j).Note;
        line.yAxis.min = this->Dbc->MsgList.at(i).SingalList.at(j).MinValue;
        line.yAxis.max = this->Dbc->MsgList.at(i).SingalList.at(j).MaxValue;
        ui->widget->Lines.append(line);

        ui->widget->getxAxisPoint();
        ui->widget->update();

        qDebug()<<ui->widget->Lines.size();

        int row = ui->tbwLine->rowCount();
        ui->tbwLine->setRowCount(row+1);
        ui->tbwLine->setColumnCount(2);

        QTableWidgetItem *tbi1 = new QTableWidgetItem(item->text(0));

        ui->tbwLine->setItem(row,0,tbi1);

        QTableWidgetItem *tbi2 = new QTableWidgetItem(item->text(1));

        ui->tbwLine->setItem(row,1,tbi2);


    }
}
